import { CURY_TYPE } from '@/store/mutation-types'
import { isEqual, isObject } from 'lodash'
export default class Crud {
  constructor(data, key = 'id') {
    this.oldData = data // 存储原始数据
    this.oldDataToObj
    this.newDataToObj
    this.primaryKey = key
  }
  getCrudType(newData) { // 根据原始数据对比脏数据
    this.oldDataToObj = this.deepFlatByForEach(this.oldData)
    this.newDataToObj = this.deepFlatByForEach(newData)
    return this.setCrudType(newData, this.oldData)
  }
  deepFlatByForEach(data) { // 展开多维数据为对象方便后续取值对比
    let res = {}
    if (typeof data === 'object') {
      if (Array.isArray(data)) {
        data.forEach(item => {
          res = { ...this.getObject(item) }
        })
      }
      if (isObject(data)) {
        res = { ...this.getObject(data) }
      }
    }
    return res
  }
  getObject(data) {
    let res = {}
    data[this.primaryKey] ? res[data[this.primaryKey]] = data : ''
    if (isObject(data)) {
      Object.keys(data).forEach(key => {
        const item = data[key]
        if (Array.isArray(item)) { // 对象下有数组时，继续向下展开
          res = { ...this.deepFlatByForEach(item), ...res }
        }
        if (isObject(item)) {
          res[item[this.primaryKey]] = item
        }
      })
    }
    return res
  }
  setCrudType(newData, oldData) { // 遍历设置数据脏数据状态
    let res
    if (newData && oldData && typeof newData === 'object' && typeof oldData === 'object') {
      if (Array.isArray(newData)) { // 数据为数组时
        res = []
        newData.forEach((item, i) => {
          const data = item
          if (isObject(item)) {
            this.setType(data)
          }
          res.push(data)
        })
        oldData.forEach(item => { // 数组判断删除项
          const data = item
          if (isObject(data) && !this.newDataToObj[item.id]) {
            data.crudType = CURY_TYPE.DELETE
            res.push(data)
          }
        })
      }
      if (isObject(newData)) { // 数据为对象时
        const data = newData
        this.setType(data)
        res = { ...data }
      }
      return res
    }
    return newData
  }
  setType(data) {
    if (!data[this.primaryKey] || !this.oldDataToObj[data[this.primaryKey]]) { // 无关键字或关键字在原始数据不存在为新增
      data.crudType = CURY_TYPE.SAVE
    } else if (!isEqual(data, this.oldDataToObj[data[this.primaryKey]])) { // 新数据与原始数据不相等为更新
      data.crudType = CURY_TYPE.UPDATE
    }
    if (data.crudType === CURY_TYPE.UPDATE) { // 数据状态为更新时，判断子对象数据状态
      Object.keys(data).forEach(key => {
        if (Array.isArray(data[key])) {
          data[key] = this.setCrudType(data[key], this.oldDataToObj[data[this.primaryKey]][key] || [])
        }
        if (isObject(data[key])) {
          data[key] = this.setCrudType(data[key], this.oldDataToObj[data[this.primaryKey]][key] || {})
        }
      })
    }
  }
}
